home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / site-packages / impacket / dcerpc / samr.py < prev    next >
Text File  |  2006-05-23  |  24KB  |  724 lines

  1. # Copyright (c) 2003-2006 CORE Security Technologies
  2. #
  3. # This software is provided under under a slightly modified version
  4. # of the Apache Software License. See the accompanying LICENSE file
  5. # for more information.
  6. #
  7. # $Id: samr.py,v 1.7 2006/05/23 21:19:26 gera Exp $
  8. #
  9. # Description:
  10. #   SAMR (Security Account Manager Remote) interface implementation.
  11. #
  12.  
  13. import array
  14. from time import strftime, gmtime
  15. from struct import *
  16.  
  17. from impacket import ImpactPacket
  18. import dcerpc
  19. import ndrutils
  20.  
  21. MSRPC_UUID_SAMR   = '\x78\x57\x34\x12\x34\x12\xcd\xab\xef\x00\x01\x23\x45\x67\x89\xac\x01\x00\x00\x00'
  22.  
  23. OP_NUM_CREATE_USER_IN_DOMAIN    = 0xC
  24. OP_NUM_ENUM_USERS_IN_DOMAIN     = 0xD
  25. OP_NUM_CREATE_ALIAS_IN_DOMAIN   = 0xE
  26.  
  27. def display_time(filetime_high, filetime_low, minutes_utc=0):
  28.     d = filetime_high*4.0*1.0*(1<<30)
  29.     d += filetime_low
  30.     d *= 1.0e-7
  31.     d -= (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
  32.     if minutes_utc == 0:
  33.         r = (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)[0]
  34.     else:
  35.         r = "%s GMT %d " % (strftime("%a, %d %b %Y %H:%M:%S",gmtime(d)), minutes_utc/60)
  36.     return r
  37.  
  38. class MSRPCUserInfo:
  39.     ITEMS = {'Account Name':0,
  40.              'Full Name':1,
  41.              'Home':2,
  42.              'Home Drive':3,
  43.              'Script':4,
  44.              'Profile':5,
  45.              'Description':6,
  46.              'Workstations':7,
  47.              'Comment':8,
  48.              'Parameters':9,
  49.              'Logon hours':10
  50.              }
  51.  
  52.     def __init__(self, data = None):
  53.         self._logon_time_low = 0
  54.         self._logon_time_high = 0
  55.         self._logoff_time_low = 0
  56.         self._logoff_time_high = 0
  57.         self._kickoff_time_low = 0
  58.         self._kickoff_time_high = 0
  59.         self._pwd_last_set_low = 0
  60.         self._pwd_last_set_high = 0
  61.         self._pwd_can_change_low = 0
  62.         self._pwd_can_change_high = 0
  63.         self._pwd_must_change_low = 0
  64.         self._pwd_must_change_high = 0
  65.         self._items = []
  66.         self._rid = 0
  67.         self._group = 0
  68.         self._acct_ctrl = 0
  69.         self._bad_pwd_count = 0
  70.         self._logon_count = 0
  71.         self._country = 0
  72.         self._codepage = 0
  73.         self._nt_pwd_set = 0
  74.         self._lm_pwd_set = 0
  75.  
  76.         if data: self.set_header(data)
  77.  
  78.     def set_header(self,data):
  79.         index = 8
  80.         self._logon_time_low, self._logon_time_high, self._logoff_time_low, self._logoff_time_high, self._kickoff_time_low,self._kickoff_time_high, self._pwd_last_set_low,self._pwd_last_set_high, self._pwd_can_change_low,self._pwd_can_change_high, self._pwd_must_change_low, self._pwd_must_change_high = unpack('<LLLLLLLLLLLL',data[index:index+48])
  81.         index += 48
  82.         for i in range(0,len(MSRPCUserInfo.ITEMS)-1):
  83.             length, size, id = unpack('<HHL',data[index:index+8])
  84.             self._items.append(dcerpc.MSRPCArray(length, size, id))
  85.             index += 8
  86.  
  87.         index += 24     # salteo los unknowns
  88.         item_count = unpack('<L',data[index:index+4])[0]
  89.         index += 4 + (item_count+1) * 4  # Esto no lo se!! salteo buffer
  90.         self._rid, self._group, self._acct_ctr,_ = unpack('<LLLL',data[index: index+16])
  91.         index += 16
  92.         logon_divisions, _, id = unpack('<HHL',data[index:index+8])
  93.         self._items.append(dcerpc.MSRPCArray(logon_divisions, _, id))
  94.         index += 8
  95.         self._bad_pwd_count, self._logon_count, self._country, self._codepage = unpack('<HHHH', data[index: index + 8])
  96.         index += 8
  97.         self._nt_pwd_set, self._lm_pwd_set,_,_= unpack('<BBBB', data[index:index+4])
  98.         index += 4
  99.  
  100.         for item in self._items[:-1]: # Except LOGON_HOUNS
  101.             if 0 == item.get_size():
  102.                 continue
  103.             max_len, offset, curlen = unpack('<LLL', data[index:index+12])
  104.             index += 12
  105.             item.set_name(unicode(data[index:index+2*curlen], 'utf-16le'))
  106.             item.set_max_len(max_len)
  107.             item.set_offset(offset)
  108.             item.set_length2(curlen)
  109.             index += 2*curlen
  110.             if curlen & 0x1: index += 2 # Skip padding.
  111.  
  112.         # Process LOGON_HOURS.
  113.         # This is a bitmask of logon_divisions bits. Normally logon_divisions is 168, one bit per hour of a whole week.
  114.         item = self._items[10]
  115.         max_len, offset, curlen = unpack('<LLL', data[index:index+12])
  116.         index += 12
  117.         item.set_name('Unlimited')
  118.         # I admit this routine is not very clever. We could do a better mapping to human readable format.
  119.         for b in data[index: index+curlen]:
  120.             if 0xFF != ord(b):
  121.                 item.set_name('Unknown')
  122.  
  123.     def get_num_items(self):
  124.         return len(self._items)
  125.     def get_items(self):
  126.         return self._items
  127.     def get_logon_time(self):
  128.         return display_time(self._logon_time_high, self._logon_time_low)
  129.     def get_logoff_time(self):
  130.         return display_time(self._logoff_time_high, self._logoff_time_low)
  131.     def get_kickoff_time(self):
  132.         return display_time(self._kickoff_time_high, self._kickoff_time_low)
  133.     def get_pwd_last_set(self):
  134.         return display_time(self._pwd_last_set_high, self._pwd_last_set_low)
  135.     def get_pwd_can_change(self):
  136.         return display_time(self._pwd_can_change_high, self._pwd_can_change_low)
  137.     def get_group_id(self):
  138.         return self._group
  139.     def get_bad_pwd_count(self):
  140.         return self._bad_pwd_count
  141.     def get_logon_count(self):
  142.         return self._logon_count
  143.     def get_pwd_must_change(self):
  144.         if self._pwd_must_change_low == 4294967295L:
  145.             return "Infinity" 
  146.         else:
  147.             return display_time(self._pwd_must_change_high, self._pwd_must_change_low)
  148.     def is_enabled(self):
  149.         return not (self._acct_ctr & 0x01)
  150.  
  151.     def print_friendly(self):
  152.         print "Last Logon: " + display_time(self._logon_time_high, self._logon_time_low)
  153.         print "Last Logoff: " + display_time(self._logoff_time_high, self._logoff_time_low)
  154.         print "Kickoff Time: " + display_time(self._kickoff_time_high, self._kickoff_time_low)
  155.         print "PWD Last Set: " + display_time(self._pwd_last_set_high, self._pwd_last_set_low)
  156.         print "PWD Can Change: " + display_time(self._pwd_can_change_high, self._pwd_can_change_low)
  157.         print "Group id: %d" % self._group
  158.         print "Bad pwd count: %d" % self._bad_pwd_count
  159.         print "Logon count: %d" % self._logon_count
  160.         if self._pwd_must_change_low == 4294967295L:
  161.             print "PWD Must Change: Infinity" 
  162.         else:
  163.             print "PWD Must Change: " + display_time(self._pwd_must_change_high, self._pwd_must_change_low)
  164.         for i in MSRPCUserInfo.ITEMS.keys():
  165.             print i + ': ' + self._items[MSRPCUserInfo.ITEMS[i]].get_name()
  166.         print
  167.         return
  168.  
  169.  
  170. class SAMRConnectHeader(ImpactPacket.Header):
  171.     OP_NUM = 0x39
  172.  
  173.     __SIZE = 4
  174.  
  175.     def __init__(self, aBuffer = None):
  176.         ImpactPacket.Header.__init__(self, SAMRConnectHeader.__SIZE)
  177.  
  178.         self.__sptr = ndrutils.NDRPointer()
  179.  
  180.         self.set_server('')
  181.         self.set_access_mask(0x2000000)
  182.  
  183.         if aBuffer: self.load_header(aBuffer)
  184.  
  185.     def get_server(self):
  186.         return ndrutils.NDRPointer(self.get_bytes()[:-4].tostring(), ndrutils.NDRString)
  187.     def set_server(self, name):
  188.         ss = ndrutils.NDRString()
  189.         ss.set_string(name)
  190.         self.__sptr.set_pointer(ss)
  191.         data = self.__sptr.rawData()
  192.         self.get_bytes()[:-4] = array.array('B', data)
  193.  
  194.     def get_access_mask(self):
  195.         return self.get_long(-4, '<')
  196.     def set_access_mask(self, mask):
  197.         self.set_long(-4, mask, '<')
  198.  
  199.  
  200.     def get_header_size(self):
  201.         var_size = len(self.get_bytes()) - SAMRConnectHeader.__SIZE
  202.         assert var_size > 0
  203.         return SAMRConnectHeader.__SIZE + var_size
  204.  
  205.  
  206. class SAMRRespConnectHeader(ImpactPacket.Header):
  207.     __SIZE = 24
  208.  
  209.     def __init__(self, aBuffer = None):
  210.         ImpactPacket.Header.__init__(self, SAMRRespConnectHeader.__SIZE)
  211.         if aBuffer: self.load_header(aBuffer)
  212.  
  213.     def get_context_handle(self):
  214.         return self.get_bytes().tostring()[:20]
  215.     def set_context_handle(self, handle):
  216.         assert 20 == len(handle)
  217.         self.get_bytes()[:20] = array.array('B', handle)
  218.  
  219.     def get_return_code(self):
  220.         return self.get_long(20, '<')
  221.     def set_return_code(self, code):
  222.         self.set_long(20, code, '<')
  223.  
  224.  
  225.     def get_header_size(self):
  226.         return SAMRRespConnectHeader.__SIZE
  227.  
  228.  
  229. class SAMREnumDomainsHeader(ImpactPacket.Header):
  230.     OP_NUM = 0x6
  231.  
  232.     __SIZE = 28
  233.  
  234.     def __init__(self, aBuffer = None):
  235.         ImpactPacket.Header.__init__(self, SAMREnumDomainsHeader.__SIZE)
  236.  
  237.         self.set_pref_max_size(8192)
  238.  
  239.         if aBuffer: self.load_header(aBuffer)
  240.  
  241.     def get_context_handle(self):
  242.         return self.get_bytes().tolist()[:20]
  243.     def set_context_handle(self, handle):
  244.         assert 20 == len(handle)
  245.         self.get_bytes()[:20] = array.array('B', handle)
  246.  
  247.     def get_resume_handle(self):
  248.         return self.get_long(20, '<')
  249.     def set_resume_handle(self, handle):
  250.         self.set_long(20, handle, '<')
  251.  
  252.     def get_pref_max_size(self):
  253.         return self.get_long(24, '<')
  254.     def set_pref_max_size(self, size):
  255.         self.set_long(24, size, '<')
  256.  
  257.  
  258.     def get_header_size(self):
  259.         return SAMREnumDomainsHeader.__SIZE
  260.  
  261.  
  262. class SAMRRespEnumDomainHeader(ImpactPacket.Header):
  263.     __SIZE = 12
  264.  
  265.     def __init__(self, aBuffer = None):
  266.         ImpactPacket.Header.__init__(self, SAMRRespEnumDomainHeader.__SIZE)
  267.         if aBuffer: self.load_header(aBuffer)
  268.  
  269.  
  270.     def get_resume_handle(self):
  271.         return self.get_long(0, '<')
  272.     def set_resume_handle(self, handle):
  273.         self.set_long(0, handle, '<')
  274.  
  275.     def get_domains(self):
  276.         return dcerpc.MSRPCNameArray(self.get_bytes()[4:-8].tostring())
  277.     def set_domains(self, domains):
  278.         assert isinstance(domains, dcerpc.MSRPCNameArray)
  279.         self.get_bytes()[4:-8] = array.array('B', domains.rawData())
  280.  
  281.     def get_entries_num(self):
  282.         return self.get_long(-8, '<')
  283.     def set_entries_num(self, num):
  284.         self.set_long(-8, num, '<')
  285.  
  286.     def get_return_code(self):
  287.         return self.get_long(-4, '<')
  288.     def set_return_code(self, code):
  289.         self.set_long(-4, code, '<')
  290.  
  291.  
  292.     def get_header_size(self):
  293.         var_size = len(self.get_bytes()) - SAMRRespEnumDomainHeader.__SIZE
  294.         assert var_size > 0
  295.         return SAMRRespEnumDomainHeader.__SIZE + var_size
  296.  
  297.  
  298. class SAMRLookupDomainHeader(ImpactPacket.Header):
  299.     OP_NUM = 0x5
  300.  
  301.     __SIZE = 20
  302.  
  303.     def __init__(self, aBuffer = None):
  304.         ImpactPacket.Header.__init__(self, SAMRLookupDomainHeader.__SIZE)
  305.         if aBuffer: self.load_header(aBuffer)
  306.  
  307.     def get_context_handle(self):
  308.         return self.get_bytes().tolist()[:20]
  309.     def set_context_handle(self, handle):
  310.         assert 20 == len(handle)
  311.         self.get_bytes()[:20] = array.array('B', handle)
  312.  
  313.     def get_domain(self):
  314.         return dcerpc.MSRPCArray(self.get_bytes().tolist()[20:])
  315.     def set_domain(self, domain):
  316.         assert isinstance(domain, dcerpc.MSRPCArray)
  317.         self.get_bytes()[20:] = array.array('B', domain.rawData())
  318.  
  319.  
  320.     def get_header_size(self):
  321.         var_size = len(self.get_bytes()) - SAMRLookupDomainHeader.__SIZE
  322.         assert var_size > 0
  323.         return SAMRLookupDomainHeader.__SIZE + var_size
  324.  
  325.  
  326. class SAMRRespLookupDomainHeader(ImpactPacket.Header):
  327.     __SIZE = 36
  328.  
  329.     def __init__(self, aBuffer = None):
  330.         ImpactPacket.Header.__init__(self, SAMRRespLookupDomainHeader.__SIZE)
  331.         if aBuffer: self.load_header(aBuffer)
  332.  
  333. ##     def get_sid_count(self):
  334. ##         return self.get_long(4, '<')
  335. ##     def set_sid_count(self, count):
  336. ##         self.set_long(4, count, '<')
  337.  
  338. ##     def get_domain_sid(self):
  339. ##         return self.get_bytes().tolist()[8:8+24]
  340. ##     def set_domain_sid(self, sid):
  341. ##         assert 24 == len(sid)
  342. ##         self.get_bytes()[8:8+24] = array.array('B', sid)
  343.  
  344.     def get_domain_sid(self):
  345.         return self.get_bytes().tolist()[4:4+28]
  346.     def set_domain_sid(self, sid):
  347.         assert 28 == len(sid)
  348.         self.get_bytes()[4:4+28] = array.array('B', sid)
  349.  
  350.     def get_return_code(self):
  351.         return self.get_long(32, '<')
  352.     def set_return_code(self, code):
  353.         self.set_long(32, code, '<')
  354.  
  355.  
  356.     def get_header_size(self):
  357.         return SAMRRespLookupDomainHeader.__SIZE
  358.  
  359.  
  360. class SAMROpenDomainHeader(ImpactPacket.Header):
  361.     OP_NUM = 0x7
  362.  
  363.     __SIZE = 52
  364.  
  365.     def __init__(self, aBuffer = None):
  366.         ImpactPacket.Header.__init__(self, SAMROpenDomainHeader.__SIZE)
  367.  
  368.         self.set_access_mask(0x304)
  369.  
  370.         if aBuffer: self.load_header(aBuffer)
  371.  
  372.  
  373.     def get_context_handle(self):
  374.         return self.get_bytes().tolist()[:20]
  375.     def set_context_handle(self, handle):
  376.         assert 20 == len(handle)
  377.         self.get_bytes()[:20] = array.array('B', handle)
  378.  
  379.     def get_access_mask(self):
  380.         return self.get_long(20, '<')
  381.     def set_access_mask(self, mask):
  382.         self.set_long(20, mask, '<')
  383.  
  384. ##     def get_sid_count(self):
  385. ##         return self.get_long(24, '<')
  386. ##     def set_sid_count(self, count):
  387. ##         self.set_long(24, count, '<')
  388.  
  389. ##     def get_domain_sid(self):
  390. ##         return self.get_bytes().tolist()[28:28+24]
  391. ##     def set_domain_sid(self, sid):
  392. ##         assert 24 == len(sid)
  393. ##         self.get_bytes()[28:28+24] = array.array('B', sid)
  394.  
  395.     def get_domain_sid(self):
  396.         return self.get_bytes().tolist()[24:24+28]
  397.     def set_domain_sid(self, sid):
  398.         assert 28 == len(sid)
  399.         self.get_bytes()[24:24+28] = array.array('B', sid)
  400.  
  401.  
  402.     def get_header_size(self):
  403.         return SAMROpenDomainHeader.__SIZE
  404.  
  405.  
  406. class SAMRRespOpenDomainHeader(ImpactPacket.Header):
  407.     __SIZE = 24
  408.  
  409.     def __init__(self, aBuffer = None):
  410.         ImpactPacket.Header.__init__(self, SAMRRespOpenDomainHeader.__SIZE)
  411.         if aBuffer: self.load_header(aBuffer)
  412.  
  413.     def get_context_handle(self):
  414.         return self.get_bytes().tolist()[:20]
  415.     def set_context_handle(self, handle):
  416.         assert 20 == len(handle)
  417.         self.get_bytes()[:20] = array.array('B', handle)
  418.  
  419.     def get_return_code(self):
  420.         return self.get_long(20, '<')
  421.     def set_return_code(self, code):
  422.         self.set_long(20, code, '<')
  423.  
  424.  
  425.     def get_header_size(self):
  426.         return SAMRRespOpenDomainHeader.__SIZE
  427.  
  428.  
  429. class SAMREnumDomainUsersHeader(ImpactPacket.Header):
  430.     OP_NUM = OP_NUM_ENUM_USERS_IN_DOMAIN
  431.  
  432.     __SIZE = 32
  433.  
  434.     def __init__(self, aBuffer = None):
  435.         ImpactPacket.Header.__init__(self, SAMREnumDomainUsersHeader.__SIZE)
  436.  
  437.         self.set_pref_max_size(3275)
  438.  
  439.         if aBuffer: self.load_header(aBuffer)
  440.  
  441.     def get_context_handle(self):
  442.         return self.get_bytes().tolist()[:20]
  443.     def set_context_handle(self, handle):
  444.         assert 20 == len(handle)
  445.         self.get_bytes()[:20] = array.array('B', handle)
  446.  
  447.     def get_resume_handle(self):
  448.         return self.get_long(20, '<')
  449.     def set_resume_handle(self, handle):
  450.         self.set_long(20, handle, '<')
  451.  
  452.     def get_account_control(self):
  453.         return self.get_long(24, '<')
  454.     def set_account_control(self, mask):
  455.         self.set_long(24, mask, '<')
  456.  
  457.     def get_pref_max_size(self):
  458.         return self.get_long(28, '<')
  459.     def set_pref_max_size(self, size):
  460.         self.set_long(28, size, '<')
  461.  
  462.  
  463.     def get_header_size(self):
  464.         return SAMREnumDomainUsersHeader.__SIZE
  465.  
  466.  
  467. class SAMRRespEnumDomainUsersHeader(ImpactPacket.Header):
  468.     __SIZE = 16
  469.  
  470.     def __init__(self, aBuffer = None):
  471.         ImpactPacket.Header.__init__(self, SAMRRespEnumDomainUsersHeader.__SIZE)
  472.         if aBuffer: self.load_header(aBuffer)
  473.  
  474.     def get_resume_handle(self):
  475.         return self.get_long(0, '<')
  476.     def set_resume_handle(self, handle):
  477.         self.set_long(0, handle, '<')
  478.  
  479.     def get_users(self):
  480.         return dcerpc.MSRPCNameArray(self.get_bytes()[4:-8].tostring())
  481.     def set_users(self, users):
  482.         assert isinstance(users, dcerpc.MSRPCNameArray)
  483.         self.get_bytes()[4:-8] = array.array('B', users.rawData())
  484.  
  485.     def get_entries_num(self):
  486.         return self.get_long(-8, '<')
  487.     def set_entries_num(self, num):
  488.         self.set_long(-8, num, '<')
  489.  
  490.     def get_return_code(self):
  491.         return self.get_long(-4, '<')
  492.     def set_return_code(self, code):
  493.         self.set_long(-4, code, '<')
  494.  
  495.  
  496.     def get_header_size(self):
  497.         var_size = len(self.get_bytes()) - SAMRRespEnumDomainUsersHeader.__SIZE
  498.         assert var_size > 0
  499.         return SAMRRespEnumDomainUsersHeader.__SIZE + var_size
  500.  
  501.  
  502. class SAMROpenUserHeader(ImpactPacket.Header):
  503.     OP_NUM = 0x22
  504.  
  505.     __SIZE = 28
  506.  
  507.     def __init__(self, aBuffer = None):
  508.         ImpactPacket.Header.__init__(self, SAMROpenUserHeader.__SIZE)
  509.  
  510.         self.set_access_mask(0x2011B)
  511.  
  512.         if aBuffer: self.load_header(aBuffer)
  513.  
  514.     def get_context_handle(self):
  515.         return self.get_bytes().tolist()[:20]
  516.     def set_context_handle(self, handle):
  517.         assert 20 == len(handle)
  518.         self.get_bytes()[:20] = array.array('B', handle)
  519.  
  520.     def get_access_mask(self):
  521.         return self.get_long(20, '<')
  522.     def set_access_mask(self, mask):
  523.         self.set_long(20, mask, '<')
  524.  
  525.     def get_rid(self):
  526.         return self.get_long(24, '<')
  527.     def set_rid(self, id):
  528.         self.set_long(24, id, '<')
  529.  
  530.  
  531.     def get_header_size(self):
  532.         return SAMROpenUserHeader.__SIZE
  533.  
  534.  
  535. class SAMRRespOpenUserHeader(ImpactPacket.Header):
  536.     __SIZE = 24
  537.  
  538.     def __init__(self, aBuffer = None):
  539.         ImpactPacket.Header.__init__(self, SAMRRespOpenUserHeader.__SIZE)
  540.         if aBuffer: self.load_header(aBuffer)
  541.  
  542.     def get_context_handle(self):
  543.         return self.get_bytes().tolist()[:20]
  544.     def set_context_handle(self, handle):
  545.         assert 20 == len(handle)
  546.         self.get_bytes()[:20] = array.array('B', handle)
  547.  
  548.     def get_return_code(self):
  549.         return self.get_long(20, '<')
  550.     def set_return_code(self, code):
  551.         self.set_long(20, code, '<')
  552.  
  553.  
  554.     def get_header_size(self):
  555.         return SAMRRespOpenUserHeader.__SIZE
  556.  
  557.  
  558. class SAMRQueryUserInfoHeader(ImpactPacket.Header):
  559.     OP_NUM = 0x24
  560.  
  561.     __SIZE = 22
  562.  
  563.     def __init__(self, aBuffer = None):
  564.         ImpactPacket.Header.__init__(self, SAMRQueryUserInfoHeader.__SIZE)
  565.  
  566.         self.set_level(21)
  567.  
  568.         if aBuffer: self.load_header(aBuffer)
  569.  
  570.     def get_context_handle(self):
  571.         return self.get_bytes().tolist()[:20]
  572.     def set_context_handle(self, handle):
  573.         assert 20 == len(handle)
  574.         self.get_bytes()[:20] = array.array('B', handle)
  575.  
  576.     def get_level(self):
  577.         return self.get_word(20, '<')
  578.     def set_level(self, level):
  579.         self.set_word(20, level, '<')
  580.  
  581.  
  582.     def get_header_size(self):
  583.         return SAMRQueryUserInfoHeader.__SIZE
  584.  
  585.  
  586. class SAMRRespQueryUserInfoHeader(ImpactPacket.Header):
  587.     __SIZE = 4
  588.  
  589.     def __init__(self, aBuffer = None):
  590.         ImpactPacket.Header.__init__(self, SAMRRespQueryUserInfoHeader.__SIZE)
  591.         if aBuffer: self.load_header(aBuffer)
  592.  
  593.     def get_user_info(self):
  594.         return MSRPCUserInfo(self.get_bytes()[:-4].tostring())
  595.     def set_user_info(self, info):
  596.         assert isinstance(info, MSRPCUserInfo)
  597.         self.get_bytes()[:-4] = array.array('B', info.rawData())
  598.  
  599.     def get_return_code(self):
  600.         return self.get_long(-4, '<')
  601.     def set_return_code(self, code):
  602.         self.set_long(-4, code, '<')
  603.  
  604.  
  605.     def get_header_size(self):
  606.         var_size = len(self.get_bytes()) - SAMRRespQueryUserInfoHeader.__SIZE
  607.         assert var_size > 0
  608.         return SAMRRespQueryUserInfoHeader.__SIZE + var_size
  609.  
  610.  
  611. class SAMRCloseRequestHeader(ImpactPacket.Header):
  612.     OP_NUM = 0x1
  613.  
  614.     __SIZE = 20
  615.  
  616.     def __init__(self, aBuffer = None):
  617.         ImpactPacket.Header.__init__(self, SAMRCloseRequestHeader.__SIZE)
  618.         if aBuffer: self.load_header(aBuffer)
  619.  
  620.     def get_context_handle(self):
  621.         return self.get_bytes().tolist()[:20]
  622.     def set_context_handle(self, handle):
  623.         assert 20 == len(handle)
  624.         self.get_bytes()[:20] = array.array('B', handle)
  625.  
  626.  
  627.     def get_header_size(self):
  628.         return SAMRCloseRequestHeader.__SIZE
  629.  
  630.  
  631. class SAMRRespCloseRequestHeader(ImpactPacket.Header):
  632.     __SIZE = 24
  633.  
  634.     def __init__(self, aBuffer = None):
  635.         ImpactPacket.Header.__init__(self, SAMRRespCloseRequestHeader.__SIZE)
  636.         if aBuffer: self.load_header(aBuffer)
  637.  
  638.     def get_context_handle(self):
  639.         return self.get_bytes().tolist()[:20]
  640.     def set_context_handle(self, handle):
  641.         assert 20 == len(handle)
  642.         self.get_bytes()[:20] = array.array('B', handle)
  643.  
  644.     def get_return_code(self):
  645.         return self.get_long(20, '<')
  646.     def set_return_code(self, code):
  647.         self.set_long(20, code, '<')
  648.  
  649.  
  650.     def get_header_size(self):
  651.         return SAMRRespCloseRequestHeader.__SIZE
  652.  
  653.  
  654. class DCERPCSamr:
  655.     def __init__(self, dcerpc):
  656.         self._dcerpc = dcerpc
  657.  
  658.     def connect(self):
  659.         samrcon = SAMRConnectHeader()
  660.         samrcon.set_server('*SMBSERVER')
  661.         self._dcerpc.send(samrcon)
  662.         data = self._dcerpc.recv()
  663.         retVal = SAMRRespConnectHeader(data)
  664.         return retVal
  665.  
  666.     def enumdomains(self,context_handle):
  667.         enumdom = SAMREnumDomainsHeader()
  668.         enumdom.set_context_handle(context_handle)
  669.         self._dcerpc.send(enumdom)
  670.         data = self._dcerpc.recv()
  671.         retVal = SAMRRespEnumDomainHeader(data)
  672.         return retVal
  673.  
  674.     def lookupdomain(self,context_handle,domain):
  675.         lookupdom = SAMRLookupDomainHeader()
  676.         lookupdom.set_context_handle(context_handle)
  677.         lookupdom.set_domain(domain)
  678.         self._dcerpc.send(lookupdom)
  679.         data = self._dcerpc.recv()
  680.         retVal = SAMRRespLookupDomainHeader(data)
  681.         return retVal
  682.  
  683.     def opendomain(self,context_handle,domain_sid):
  684.         opendom = SAMROpenDomainHeader()
  685.         opendom.set_context_handle(context_handle)
  686.         opendom.set_domain_sid(domain_sid)
  687.         self._dcerpc.send(opendom)
  688.         data = self._dcerpc.recv()
  689.         retVal = SAMRRespOpenDomainHeader(data)
  690.         return retVal
  691.  
  692.     def enumusers(self,context_handle):
  693.         enumusers = SAMREnumDomainUsersHeader()
  694.         enumusers.set_context_handle(context_handle)
  695.         self._dcerpc.send(enumusers)
  696.         data = self._dcerpc.recv()
  697.         retVal = SAMRRespEnumDomainUsersHeader(data)
  698.         return retVal
  699.  
  700.     def openuser(self,context_handle, rid):
  701.         openuser = SAMROpenUserHeader()
  702.         openuser.set_context_handle(context_handle)
  703.         openuser.set_rid(rid)
  704.         self._dcerpc.send(openuser)
  705.         data = self._dcerpc.recv()
  706.         retVal = SAMRRespOpenUserHeader(data)
  707.         return retVal
  708.  
  709.     def queryuserinfo(self,context_handle):
  710.         userinfo = SAMRQueryUserInfoHeader()
  711.         userinfo.set_context_handle(context_handle)
  712.         self._dcerpc.send(userinfo)
  713.         data = self._dcerpc.recv()
  714.         retVal = SAMRRespQueryUserInfoHeader(data)
  715.         return retVal
  716.  
  717.     def closerequest(self,context_handle):
  718.         closereq = SAMRCloseRequestHeader()
  719.         closereq.set_context_handle(context_handle)
  720.         self._dcerpc.send(closereq)
  721.         data = self._dcerpc.recv()
  722.         retVal = SAMRRespCloseRequestHeader(data)
  723.         return retVal
  724.